#pragma once

#include <iostream>
#include <mysql/mysql.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <vector>
#include <sys/socket.h>
#include <string> 
#include <google/template.h>   
#include "../util.hpp"

using std::cout;
using std::endl;
using std::string;
using namespace google;

void  DataBaseInit(MYSQL*& conn){
    conn = mysql_init(NULL);
    //设置连接的字符集为utf8，不然没法显示中文
    mysql_set_character_set(conn,"utf8");
    if(conn == NULL)
        cout << "Error " << mysql_errno(conn) << ": " << mysql_error(conn);
    if(mysql_real_connect(conn,"localhost","root","1","news",0,NULL,0) == NULL)
        cout << "Error " << mysql_errno(conn) << ": " << mysql_error(conn);
}

class OperateTopic{
public:
    //增加主题
    static void AddTopic(MYSQL* conn,string name){
        string info = "insert into topic(name) values('";
        info += name + "')";
        cout << info << endl;
        mysql_query(conn,info.c_str());
    } 

    //删除主题(根据id)
    static void DeleteTopic(MYSQL* conn,int id){
        string info = "delete from topic where id=";
        info += std::to_string(id);
        cout << info << endl;
        mysql_query(conn,info.c_str());

        //删除主题下的所有新闻
        info = "delete from news where topicid=";
        info += std::to_string(id);
        cout << info << endl;
        mysql_query(conn,info.c_str());
    }

    //删除主题(根据名字)
    static void DeleteTopic(MYSQL* conn,string name){
        string info = "delete from topic where name='";
        info += name + "'";
        cout << info << endl;
        mysql_query(conn,info.c_str());
    }

    //取出当前所有主题
    static std::vector<string> AllTopic(MYSQL* conn){
        MYSQL_RES* result;
        MYSQL_ROW row;

        mysql_query(conn,"select name from topic");
        result = mysql_store_result(conn);
        std::vector<string> ret;
        while((row = mysql_fetch_row(result))){
            ret.push_back((row[0]));
        }
        
        return ret;
    }

    //取出对应主题的id
     static int IdOfTopic(MYSQL* conn,string name){
        JudgeTopic(conn,name);
        MYSQL_RES* result;
        MYSQL_ROW row;

        string info = "select id from topic where name='";
        info += name + "'";
        mysql_query(conn,info.c_str());
        result = mysql_store_result(conn);
        int ret;
        while((row = mysql_fetch_row(result))){
            ret = atoi(row[0]);
        }
        return ret;
    } 
    
    //判定主题名是否存在
    //这里有两种情况下会用到
    //第一种是管理员添加主题的时候，这个时候用第一个版本的
    //第二种是管理员添加新闻的时候，因为新闻表里只有topicid
    //所以用第二个版本的
    static bool JudgeTopic(MYSQL* conn,string name){
        MYSQL_RES* result;
        MYSQL_ROW row;

        string info = "select id  from topic where name='";
        info += name + "'";
        mysql_query(conn,info.c_str());
        result = mysql_store_result(conn);
        row = mysql_fetch_row(result);
        if(row == NULL){
            //如果topicid不存在，则返回
            return false;
        }
        return true;
    }

    static bool JudgeTopic(MYSQL* conn,int topicid){
        MYSQL_RES* result;
        MYSQL_ROW row;

        string info = "select id from topic where id=";
        info += std::to_string(topicid);
        mysql_query(conn,info.c_str());
        result = mysql_store_result(conn);
        row = mysql_fetch_row(result);
        if(row == NULL){
            //如果topicid不存在，则返回
            return false;
        }
        return true;
    }
};

class OperateNews{
public:
    //添加新闻,要对topicID进行判定是否存在
    static void AddNews(MYSQL* conn,int topicid,string title,string author,string content){
        if(OperateTopic::JudgeTopic(conn,topicid)){
            string info = "insert into news(topicid,title,author,content) values(";
            info += std::to_string(topicid) + ",'" + title + "','" + author + "','" + content + "')";
            mysql_query(conn,info.c_str());
        }
    }

    //删除新闻
    static void DeleteNews(MYSQL* conn,int id){
        string info = "delete from news where id=";
        info += std::to_string(id);
        mysql_query(conn,info.c_str());

        //删除所属新闻的评论
        info = "delete from comment where newsid=";
        info += std::to_string(id);
        mysql_query(conn,info.c_str());
    }

    //修改新闻
    static void ModifyNews(MYSQL* conn,int id,string what,string modify){
        string info = "update news set ";
        info += what + "='" + modify + "' where id=" + std::to_string(id);
        mysql_query(conn,info.c_str());
    }

    //取出最新的十条新闻(按发布日期,不按修改日期)
    //不到十条就全部取出来
    static std::vector<string> LatestTenNews(MYSQL* conn){
        MYSQL_RES* result;
        MYSQL_ROW row;

        mysql_query(conn,"select title from news order by createdate desc");
        result = mysql_store_result(conn);
        std::vector<string> ret;
        int count = 1;
        while((row = mysql_fetch_row(result))){
            ret.push_back(row[0]);
            if( count < 10 )
                ++count;
            else
                break;
        }
        return ret;
    }

    //取出主题下的所有新闻
    //在调用该函数之前，需要先判定topicid是否存在
    static std::vector<int> AllOfTheTopicNews(MYSQL* conn,int topicid){
        MYSQL_RES* result;
        MYSQL_ROW row;

        string info = "select id from news where topicid=";
        info += std::to_string(topicid);
        mysql_query(conn,info.c_str());
        result = mysql_store_result(conn);
        std::vector<int> ret;
        while((row = mysql_fetch_row(result))){
            ret.push_back(atoi(row[0]));
        }
        return ret;
    }

    //获取新闻简略信息
    static void GetNew1(MYSQL* conn,int topicid,std::vector<string>& title,
             std::vector<string>& author,std::vector<string>& createdate){
        MYSQL_RES* result;
        MYSQL_ROW row;
        string sqlstate = "select title,author,createdate from news where topicid=";
        sqlstate += std::to_string(topicid);
        sqlstate += " order by createdate desc";
        mysql_query(conn,sqlstate.c_str());
        result = mysql_store_result(conn);
        while((row = mysql_fetch_row(result))){
            title.push_back(row[0]);
            author.push_back(row[1]);
            createdate.push_back(row[2]);
        }
    }

    //获取新闻具体信息
    static void GetNew2(MYSQL* conn,const string& title,string& author,string& date,string& content,string& id){
        MYSQL_RES* result;
        MYSQL_ROW row;
        string sqlstate = "select author,createdate,content,id from news where title='";
        sqlstate += title;
        sqlstate += "'";
        mysql_query(conn,sqlstate.c_str());
        result = mysql_store_result(conn);
        row = mysql_fetch_row(result);
        author = row[0];
        date = row[1];
        content = row[2];
        id = row[3];
    }

};

class OperateUser{
public:
    static bool IsUserExist(MYSQL* conn,string name,string pwd){
        MYSQL_RES* result;
        MYSQL_ROW row;

        string info = "select pwd from user where name='";
        info += name + "'";
        mysql_query(conn,info.c_str());
        result = mysql_store_result(conn);
        row = mysql_fetch_row(result);
        if(row == NULL)
            return false;
        if(strcmp(row[0],pwd.c_str()) == 0)
            return true;
        else
            return false;
        
        return true;
    }   

    static void AddUser(MYSQL* conn,string name,string pwd){
        string info = "insert into user(name,pwd) values('";
        info += name + "','" + pwd + "')";
        mysql_query(conn,info.c_str());
    }

    static void ModifyUser(MYSQL* conn,string name,string what,string newone){
        string info = "update user set ";
        info += what + "='" + newone + "' where name='" + name + "'";
        mysql_query(conn,info.c_str());
    }

    static int IdofUser(MYSQL* conn,string name){
        MYSQL_RES* result;
        MYSQL_ROW row;

        string info = "select id from user where name='";
        info += name + "'";
        mysql_query(conn,info.c_str());
        result = mysql_store_result(conn);
        int ret;
        while((row = mysql_fetch_row(result))){
            ret = atoi(row[0]);
        }
        return ret;        
    }

    static string NameofUser(MYSQL* conn,string userid){
        MYSQL_RES* result;
        MYSQL_ROW row;

        string info = "select name from user where id=";
        info += userid;
        mysql_query(conn,info.c_str());
        result = mysql_store_result(conn);
        row = mysql_fetch_row(result);
        string name = row[0];
        
        return name;        
    }
};

class OperateComment{
public:
    //添加评论
    //添加之前需要判定newsid是否存在
    static void AddComment(MYSQL* conn,string newsid,string content,string author){
        int userid = OperateUser::IdofUser(conn,author);
        string info = "insert into comment(newsid,content,userid) values(";
        info += newsid + ",'" + content + "'," + std::to_string(userid) + ")";
        mysql_query(conn,info.c_str());
    }

    //删除评论
    static void DeleteComment(MYSQL* conn,int id){
        string info = "delete from comment where id=";
        info += std::to_string(id);
        mysql_query(conn,info.c_str());
    }

    //取出对应新闻下的所有评论
    static std::vector<string> GetComment(MYSQL* conn,string newsid,std::vector<string>& comments){
        MYSQL_RES* result;
        MYSQL_ROW row;

        string info = "select userid,content,date from comment where newsid=";
        info += newsid;
        mysql_query(conn,info.c_str());
        result = mysql_store_result(conn);

        while((row = mysql_fetch_row(result))){
            string name = OperateUser::NameofUser(conn,row[0]);
            string tmp;
            tmp += "评论者：";
            tmp += name;
            tmp += "  评论内容：";
            tmp += row[1];
            tmp += "                          评论日期：";
            tmp += row[2];
            comments.push_back(tmp);
        }
        
        return comments;
    }
};





